home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 06 - 1990 / 06.02 Feb 90 / Bit Mapper Source / BTMP1 / BitMapper_main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-11-19  |  9.8 KB  |  378 lines  |  [TEXT/KAHL]

  1. /* ======================================= *
  2.     file:    BitMapper_main.c
  3.     date:    11.13.89
  4.  * --------------------------------------- *
  5.     Copyright © 1989, Michael Ogawa and
  6.     MacTutor — All Rights Reserved.
  7.  * ======================================= */
  8.  
  9. /* #include <MacHeaders> */
  10. #include "BitMapper.h"
  11.  
  12. #ifdef applec
  13. #    include <Desk.h>
  14. #    include <Scrap.h>
  15. #    include <Packages.h>
  16.     typedef char    SignedByte;
  17. #endif applec
  18.  
  19.  
  20. /* Code resource entry point (MPW) ======= */
  21.  
  22. #ifdef applec
  23. pascal void BitMapper(short selector,
  24.     MenuDataPtr toolInfo, long *refCon,
  25.     short *returnCode)
  26. /*    Code resource entry point for a
  27. SuperPaint transformation command plug-in
  28. tool built in MPW C.  This avoids having to
  29. forward reference all the internal
  30. routines. */
  31. /*    m_o 06.23.89 */
  32. {
  33.     main(selector, toolInfo, refCon,
  34.         returnCode);
  35. }
  36. #endif applec
  37.  
  38.  
  39. /* private functions ===================== */
  40.  
  41. static short OpenOutput(
  42.     TBitMapperPtr pMyInfo)
  43. /*    Prepares the appropriate output method.
  44. PMyInfo is a pointer to a BitMapper record
  45. containing information about the currently
  46. executing command.
  47.     This version of OpenOutput() simply
  48. prepares output to the desk scrap.  The
  49. clipboard is cleared, and as a workaround for
  50. MultiFinder’s selective updating of other
  51. partitions’ ScrapCount low-memory variable,
  52. SystemEdit() is called with the copy message.
  53. (See “Macintosh Technical Note #180:
  54. MultiFinder Miscellanea” for details.)
  55.     If no error occured then the result code
  56. noErr is returned as the function return
  57. value; otherwise an appropriate Operating
  58. System result code is returned as the
  59. function return value. */
  60. /*    m_o 11.13.89 */
  61. {
  62. #    pragma unused(pMyInfo)
  63.  
  64.     /* MultiFinder work-around: notify
  65.        System of copy operation… */
  66.     (void)SystemEdit(3);
  67.     /* clear the desk scrap… */
  68.     return(ZeroScrap());
  69. }
  70.  
  71.  
  72. static short DoOutput(Handle hData,
  73.     ResType rType, TBitMapperPtr pMyInfo)
  74. /*    Outputs the data in the relocatable
  75. block specified by the handle hData.  The
  76. data output format is specified by rType.
  77. PMyInfo is a pointer to a BitMapper record
  78. containing information about currently
  79. executing command.
  80.     This version of DoOutput() simply sends
  81. the data to the clipboard using the Toolbox
  82. routine PutScrap(), specifying rType as the
  83. Desk scrap data type.  Note that it does not
  84. call ZeroScrap(), so the output is added to
  85. the current scrap content as an additional
  86. type.  This is not good if the scrap already
  87. contains a resource of the specified type.
  88. Therefore, ZeroScrap() should be called once
  89. before outputting any data to the scrap.
  90.     If no error occured then the result code
  91. noErr is returned as the function return
  92. value; otherwise an appropriate Operating
  93. System result code is returned as the
  94. function return value. */
  95. /*    m_o 11.13.89 */
  96. {
  97. #    pragma unused(pMyInfo)
  98.     SignedByte savedMPFlags;
  99.     short result;
  100.  
  101.     /* get master pointer flags and lock down… */
  102.     savedMPFlags = HGetState(hData);
  103.     MoveHHi(hData);
  104.     HLock(hData);
  105.  
  106.     result = PutScrap(GetHandleSize(hData),
  107.         rType, *hData);
  108.  
  109.     /* restore master pointer state… */
  110.     HSetState(hData, savedMPFlags);
  111.  
  112.     return(result);
  113. }
  114.  
  115.  
  116. static void CopyBits2Buffer(
  117.     const BitMap *pSrcBMap,
  118.     const Rect *pSrcRect, Ptr pBuffer,
  119.     short bufferRowBytes, short mode)
  120. /*    Transfers a bit image specified by the
  121. bit map *pSrcMap to the image buffer
  122. pBuffer[].  The image buffer must begin on an
  123. even address.  The width, in bytes, of the
  124. destination buffer is specified by
  125. bufferRowBytes, which must also be even.
  126.     The bits enclosed by the source
  127. rectangle *pSrcRect are transferred to a
  128. similar sized rectangle in the destination
  129. image.  The destination rectangle is the same
  130. size as the source rectangle and is aligned
  131. at the top left corner of the destination bit
  132. image.  The destination image buffer must be
  133. big enough to accomodate the entire image
  134. being transferred.  The transfer mode is
  135. specified by the mode parameter. */
  136. /*    m_o 06.22.89 */
  137. {
  138.     BitMap dstBMap;
  139.  
  140.     dstBMap.baseAddr = pBuffer;
  141.     dstBMap.rowBytes = bufferRowBytes;
  142.     dstBMap.bounds = *pSrcRect;
  143.     CopyBits(pSrcBMap, &dstBMap, pSrcRect,
  144.         pSrcRect, mode, NULL);
  145. }
  146.  
  147.  
  148. static short PutPICT(TBitMapperPtr pMyInfo)
  149. /*    Makes a picture that is a copy of the
  150. selection area our command is working with,
  151. then outputs the picture.  PMyInfo is a
  152. pointer to a BitMapper record containing
  153. information about currently executing
  154. command.  This includes a grafPtr to the
  155. document port (which is also the current
  156. port).
  157.     Before calling us, SuperPaint has
  158. already set the port’s portRect to be
  159. equivalent to the selection bounding
  160. rectangle in a coordinate system local to the
  161. selection.  That is, portRect.topLeft is
  162. (0,0), portRect.bottom is equal to the height
  163. of the selection area, and portRect.right is
  164. equal to the width of the selection area.
  165.     If no error occured then the result code
  166. noErr is returned as the function return
  167. value; otherwise an appropriate Operating
  168. System result code is returned as the
  169. function return value. */
  170. /*    m_o 09.13.89 */
  171. {
  172.     short result;
  173.     PicHandle hMyPic;
  174.  
  175.     if (hMyPic = OpenPicture(
  176.         &pMyInfo->drawGptr->portRect)) {
  177.         /* copy selection… */
  178.         CopyBits(
  179.             &pMyInfo->drawGptr->portBits,
  180.             &pMyInfo->drawGptr->portBits,
  181.             &pMyInfo->drawGptr->portRect,
  182.             &pMyInfo->drawGptr->portRect,
  183.             srcCopy, NULL);
  184.         ClosePicture();
  185.         result = DoOutput((Handle)hMyPic,
  186.             'PICT', pMyInfo);
  187.         KillPicture(hMyPic);
  188.     } else
  189.         result = MemError();
  190.     return(result);
  191. }
  192.  
  193.  
  194. static short PutBTMP(TBitMapperPtr pMyInfo)
  195. /*    Makes a 'BTMP' resource from the
  196. selection area our command is working with,
  197. then outputs the resource.  PMyInfo is a
  198. pointer to a BitMapper record containing
  199. information about the currently executing
  200. command.  This includes a grafPtr to the
  201. document port (which is also the current
  202. port).
  203.     Before calling us, SuperPaint has
  204. already set the port’s portRect to be
  205. equivalent to the selection bounding
  206. rectangle in a coordinate system local to the
  207. selection.  That is, portRect.topLeft is
  208. (0,0), portRect.bottom is equal to the height
  209. of the selection area, and portRect.right is
  210. equal to the width of the selection area.
  211.     If no error occured then the result code
  212. noErr is returned as the function return
  213. value; otherwise an appropriate Operating
  214. System result code is returned as the
  215. function return value. */
  216. /*    m_o 09.17.89 */
  217. {
  218.     long sz;
  219.     short result;
  220.     BitMap myMap;
  221.     TBTMPPkHndl hMyBTMP;
  222.  
  223.     /* set up BitMap: init baseAddr… */
  224.     myMap.baseAddr = NULL;
  225.     /* get bounds rectangle… */
  226.     myMap.bounds =
  227.         pMyInfo->drawGptr->portRect;
  228.     /* calc rowBytes… */
  229.     myMap.rowBytes =
  230.         BITS2ROWBYTES(WIDTH(myMap.bounds));
  231.     /* calc size of 'BTMP' resource… */
  232.     sz = sizeof(TBTMP) +
  233.         myMap.bounds.bottom *
  234.         myMap.rowBytes;
  235.  
  236.     /* get ‘clean’ memory for new
  237.        'BTMP' resource… */
  238.     if (!(hMyBTMP =
  239.         (TBTMPPkHndl)NewHandleClear(sz)))
  240.         return(MemError());
  241.  
  242.     /* copy BitMap… */
  243.     (**hMyBTMP).map = myMap;
  244.  
  245.     /* copy bit image… */
  246.     MoveHHi((Handle)hMyBTMP);
  247.     HLock((Handle)hMyBTMP);
  248.     CopyBits2Buffer(
  249.         &pMyInfo->drawGptr->portBits,
  250.         &myMap.bounds,
  251.         (Ptr)&(**hMyBTMP).image,
  252.         myMap.rowBytes, srcCopy);
  253.     HUnlock((Handle)hMyBTMP);
  254.  
  255.     /* ship it! */
  256.     result = DoOutput((Handle)hMyBTMP,
  257.         'BTMP', pMyInfo);
  258.  
  259.     /* clean up and leave… */
  260.     DisposHandle((Handle)hMyBTMP);
  261.     return(result);
  262. }
  263.  
  264.  
  265. static short DoIt(TBitMapperPtr pMyInfo)
  266. /*    Makes a 'BTMP' resource and a picture
  267. from the selection area our command is
  268. working with, then outputs the resources.
  269. PMyInfo is a pointer to a BitMapper record
  270. containing information about currently
  271. executing command.  All its fields should be
  272. filled in on entry, except the drawGptr field
  273. which this routine fills in.  (The drawGptr
  274. field is a grafPtr to the document port,
  275. which is also the current port.)
  276.     If no error occured then the result code
  277. noErr is returned as the function return
  278. value; otherwise an appropriate Operating
  279. System result code is returned as the
  280. function return value. */
  281. /*    m_o 08.29.89 */
  282. {
  283.     short result;
  284.  
  285.     GetPort(&pMyInfo->drawGptr);
  286.     if ((result = OpenOutput(pMyInfo)) ==
  287.         noErr) {
  288.         short result2;
  289.  
  290.         result = PutBTMP(pMyInfo);
  291.         if ((result2 = PutPICT(pMyInfo)) !=
  292.             noErr && result == noErr)
  293.             result = result2;
  294.     }
  295.     return(result);
  296. }
  297.  
  298.  
  299. static void AlertErr(short err,
  300.     short baseID)
  301. /*    Puts up an alert telling the user an
  302. error occured.  Err is the result code of
  303. the error.  This is converted to a string
  304. and substituted for param text ^0 in the
  305. alert.
  306.     BaseID is the resource ID of the first
  307. (numerically lowest) resource in our plug-in
  308. tool.  Because resource IDs may be
  309. reassigned, we calculate our alert’s current
  310. resource ID based on this. */
  311. /*    m_o 09.30.89 */
  312. {
  313.     Str255 s;
  314.     unsigned char str0 = '\0';
  315.  
  316.     /* Convert error ID to string format,
  317.        put into param text ^0.  Note usage
  318.        of “str0” because we can’t have any
  319.        globals.  Not even empty strings! */
  320.     NumToString(err, s);
  321.     ParamText(s, &str0, &str0, &str0);
  322.     /* The following line would be illegal!!
  323.        ParamText(s, "", "", ""); */
  324.  
  325.     CenterWindow('ALRT',
  326.         baseID + kALRT_Err);
  327.     /* make sure cursor is arrow… */
  328.     InitCursor();
  329.  
  330.     NoteAlert(baseID + kALRT_Err, NULL);
  331. }
  332.  
  333. /* entry points ========================== */
  334.  
  335. pascal void main(short selector,
  336.     MenuDataPtr toolInfo, long *refCon,
  337.     short *returnCode)
  338. /*    Entry point and command dispatcher for
  339. the BitMapper plug-in command tool.  Selector
  340. is a call type code as defined by Silicon
  341. Beach Software in the Menu Command Interface
  342. section of their plug-in documentation
  343. “Developing Plug-In Modules for SuperPaint”.
  344. */
  345. /*    m_o 08.29.89 */
  346. {
  347.     TBitMapperRec myInfo;
  348.  
  349.     switch (selector) {
  350.     case menuAbout:
  351.         /* tell SuperPaint we have TEXT
  352.            resource for About Box info… */
  353.         *returnCode = textAbout;
  354.         break;
  355.     case menuOptions:
  356.         /* tell SuperPaint we don’t need
  357.            a scratch buffer… */
  358.         ((MenuOptionsPtr)toolInfo)->
  359.             usesScratch = false;
  360.         *returnCode = noErr;
  361.         break;
  362.     case menuSelected:
  363.         /* setup private data record
  364.            and do it!… */
  365.         myInfo.pToolInfo = toolInfo;
  366.         myInfo.pRefCon = refCon;
  367.         *returnCode = DoIt(&myInfo);
  368.         break;
  369.     }
  370.  
  371.     /* alert user on errors… */
  372.     if (*returnCode != noErr &&
  373.         selector != menuAbout)
  374.         AlertErr(*returnCode,
  375.             toolInfo->toolID);
  376.     return;
  377. }
  378.